package com.zyn.java8.lambda;

import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.stream.Collectors;

/**
 * map跟reduce操作是函数式编程的核心，reduce也被称作折叠操作。reduce并不是一种新的操作，在SQL中我们用的一些聚集函数比如sum，avg，count等
 * 他们实际上也是reduce操作，因为他们也是将多个值进行操作然后返回一个值。Stream API定义了reduce函数，可以接受一个Lambda表达式然后组合所有值。
 * Stream类中像IntStream都有内置的方法像average(), count(), sum(), mapToLong(), mapToDouble()等转换方法。
 * 我们可以用内置的方法也可以自定义。
 * 
 * @author tongyufu
 *
 */
public class MapReduce {

    public static void main(String[] args) {
        MapReduce.map();
        MapReduce.reduce();
        MapReduce.summaryStatistics();
    }

    public static void map() {
        List<Integer> costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
        costBeforeTax.stream().map(cost -> cost * 1.2).forEach(System.out::println);

        List<String> G7 = Arrays.asList("USA", "Japan", "France", "Germany", "Italy", "U.K.",
            "Canada");
        String G7Countries = G7.stream().map(x -> x.toUpperCase())
            .collect(Collectors.joining(", "));
        System.out.println(G7Countries);
    }

    public static void reduce() {
        List<Integer> costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
        double total = 0;
        for (Integer cost : costBeforeTax) {
            double price = cost + 0.12 * cost;
            total += price;
        }
        System.out.println("原有写法：" + total);

        //Lambda写法
        total = costBeforeTax.stream().map(cost -> cost + cost * 0.12)
            .reduce((sum, cost) -> sum + cost).get();
        System.out.println("Lambda写法：" + total);
    }

    public static void summaryStatistics() {
        List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29);
        IntSummaryStatistics stats = primes.stream().mapToInt(x -> x).summaryStatistics();
        System.out.println("Highest prime number in List : " + stats.getMax());
        System.out.println("Lowest prime number in List : " + stats.getMin());
        System.out.println("Sum of all prime numbers : " + stats.getSum());
        System.out.println("Average of all prime numbers : " + stats.getAverage());
    }
}
